package net.zabuchy.project.action;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
 
import net.zabuchy.activities.dao.ActivityDao;
import net.zabuchy.activities.entity.HistoryAttribute;
import net.zabuchy.activities.entity.History_event;
import net.zabuchy.address.entity.Address;
import net.zabuchy.helper.ParamNames;
import net.zabuchy.helper.SessionHelper;
import net.zabuchy.iteration.entity.Iteration;
import net.zabuchy.project.bo.ProjectBo;
import net.zabuchy.project.entity.Project;
import net.zabuchy.user.bo.UserBo;
import net.zabuchy.user.entity.User;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
 
public class CreateProjectAction extends  ActionSupport 
	implements ServletRequestAware,ServletResponseAware{ 
 
	@Autowired
    private SessionHelper sessionBean;
	@Autowired
	private ProjectBo projectBo;
	@Autowired
	private UserBo userBo;
	@Autowired
	private ActivityDao activityDao;
	    
	private HttpServletRequest request;
	private HttpServletResponse response;
	
    private static final Logger LOGGER = Logger.getLogger(CreateProjectAction.class.getName());
 
    private List projects;
 
    private Integer projectId;
	private Integer customerId;
	private String title;
	private String description;
	private String status;
	private Integer defaultIterationLenght;
	private Integer nextIterationLenght;
	private Integer currentIterationNumber;
	private Date creationdate;
	private Date predictedEndDate;
    
	private Set<User> users = new HashSet<User>(0);
	private Set<Iteration> iterations = new HashSet<Iteration>(0);
	
	private List<String> usersSystem = new ArrayList<String>(0);
	private String addedUser;
	private Integer userId;
	
	private Project project;
   
	public String execute() {
		LOGGER.debug("addForm");
		String returnInputProjectForm = request.getParameter(ParamNames.CREATE_NEW_PROJECT_FORM);
		
		boolean returnForm = (returnInputProjectForm != null ? 
				Boolean.parseBoolean(returnInputProjectForm) : false);
		
		List<User> tmp = userBo.findByCustomerId(sessionBean.getCustomerId());
		Iterator it = tmp.iterator();
		while(it.hasNext()) {
			User user = (User) it.next();
			usersSystem.add(user.getUsername());
		}
		LOGGER.debug("usersSystem.size" + usersSystem.size());
		if(returnForm) {
			LOGGER.debug("clear all fields and return form");
			clearFields();
			return Action.INPUT;
		}
		
		project = new Project();
		project.setCustomerId(sessionBean.getCustomerId());
		project.setCreationdate(new Date(System.currentTimeMillis()));
		project.setCurrentIterationNumber(1);
		project.setDefaultIterationLenght(defaultIterationLenght);
		project.setDescription(description);
		project.setNextIterationLenght(nextIterationLenght);
		project.setPredictedEndDate(predictedEndDate);
		project.setStatus("open");
		project.setTitle(title);
		
		projectBo.add(project);
		
		this.projectId = project.getProjectId();
		
		return Action.SUCCESS;
	}
    
	public String setProjectUsers() {
		
		User user = userBo.findByUsername(addedUser);
		LOGGER.debug("user.userName " + user.getUsername());
		users.add(user);
		project.setUsers(users);
		projectBo.update(project);
		
		return Action.SUCCESS;
	}
	
	public String removeUsers() {
		
		if (userBo == null) {
            return Action.ERROR;
        }
        User user = userBo.findById(userId);
        if (user == null) {
            return Action.ERROR;
        }
        
        LOGGER.debug("Remove user " + user.getUsername() + " with id " + user.getUserId() + " from project: " + projectId);
        LOGGER.debug("users: " + users.size());
        Iterator it = users.iterator();
        Set<User> temporary = new HashSet<User>(0);
        while(it.hasNext()) {
        	User tmp = (User) it.next();
        	if(user.getUserId() != tmp.getUserId()) {
        		temporary.add(tmp);
        	}
        }
        users.clear();
        users.addAll(temporary);
        LOGGER.debug("participants.size: " + users.size());
        project.setUsers(users);
        projectBo.update(project);
        
		return Action.SUCCESS;
	}
	
    private void clearFields() {
    	LOGGER.debug("TO DO");
    	this.title = null;
    	this.description = null;
    	this.status = null;
    	this.defaultIterationLenght = null;
    	this.nextIterationLenght = null;
    	this.currentIterationNumber = null;
    	this.creationdate = null;
    	this.predictedEndDate = null;
    	
    	//this.users = null;
    	this.iterations = null;
    	
    	this.addedUser = null;
    	this.userId = null;
    	
    	this.project = null;
    }
    
    
    public String listAll() {
        if (projectBo == null) {
            return Action.ERROR;
        }
        
        String projId = "";
        projId = request.getParameter("projectId");
    	LOGGER.debug("editProjectForm projectId from request : " + projId);
        
        LOGGER.debug("Get all projects");
        projects = projectBo.findAll();
        LOGGER.debug("Project number = " + projects.size());
        return Action.SUCCESS;
    }
 
    public String delete() {
        if (projectBo == null) {
            return Action.ERROR;
        }
 
        Project project = getProject(projectId);
        if (project == null) {
            return Action.ERROR;
        }
 
        LOGGER.debug("Delete project " + project.getTitle() + " with title " + project.getDescription());
        projectBo.delete(project);
        return Action.SUCCESS;
    }
 
    public String add() {
        if (projectBo == null) {
            return Action.ERROR;
        }
        String projId = "";
        projId = request.getParameter("projectId");
    	LOGGER.debug("editProjectForm projectId from request : " + projId);
        
 
        Project project = new Project();
        project.setTitle(title);
        project.setDescription(description);
        project.setCustomerId(customerId);
        project.setDefaultIterationLenght(defaultIterationLenght);
        LOGGER.debug("Add project: " + project.getTitle());
        projectBo.add(project);
        return Action.SUCCESS;
    }
 
    
    public String editProjectForm() {
    	if (projectBo == null) {
            return Action.ERROR;
        }
    	
    	String projId = request.getParameter("projectId");
    	LOGGER.debug("editProjectForm projectId from request : " + projId);
    	LOGGER.debug("editProjectForm projectId: " + projectId);
    	Project project = projectBo.findById(projectId);
    	this.title = project.getTitle();
    	this.description = project.getDescription();
    	this.customerId = project.getCustomerId();
		return Action.SUCCESS;
    	
    }
    
    
    public String edit() {
        if (projectBo == null) {
            return Action.ERROR;
        }
        
        String projId = "";
        projId = request.getParameter("projectId");
    	LOGGER.debug("editProjectForm projectId from request : " + projId);
        
        LOGGER.debug("edit projectId: " + projectId);
        Project project = projectBo.findById(projectId);
        project.setTitle(title);
        project.setCustomerId(customerId);
        project.setDescription(description);
        projectBo.edit(project);
        
        
        //// test dodawania userow
        Address address1 = new Address("city", "countryyy", "blaaa", "","blaaaada");
        Address address2 = new Address("city2", "countryyy2", "blaaa2", "","blaaaada2");
        User user1 = new User();
        user1.setCustomerId(1);
        user1.setUsername("user1");
        user1.setPassword("dupa");
        User user2 = new User();
        user2.setCustomerId(1);
        user2.setUsername("user2");
        user2.setPassword("dupa");
        user1.setAddress(address1);
        user2.setAddress(address2);
        
        if(activityDao == null) {
        	return Action.ERROR;
        }
        
        //test history Event
        History_event h1 = new History_event();
        h1.setSummary("dupa");
        h1.setDescription("opis dupy");
        
        HistoryAttribute attr1 = new HistoryAttribute();
        attr1.setName("attr1");
        attr1.setValue("value of attr 1");
        attr1.setHistoryEvent(h1);
        HistoryAttribute attr2 = new HistoryAttribute();
        attr2.setName("attr2");
        attr2.setValue("value of attr 2");
        attr2.setHistoryEvent(h1);
        
        h1.getHistoryAttributes().add(attr1);
        h1.getHistoryAttributes().add(attr2);
        
        activityDao.add(h1);
        
        List h2 = activityDao.findAll();
        History_event h3 = (History_event) activityDao.findById(1).get(0);
        
        LOGGER.debug("EditProject - historyEvent.attr.size:  " + h2.size());
        LOGGER.debug("EditProject - historyEvent.attr.size:  " + h3.getHistoryAttributes().size());
        for(HistoryAttribute attribute : h3.getHistoryAttributes()) {
        	LOGGER.debug("attribute : name: " + attribute.getName() + ", value: " + attribute.getValue());
        }
        
        //   END test history Event
        
        if (userBo == null) {
            return Action.ERROR;
        }
        userBo.add(user1);
        userBo.add(user2);
        
        
        
        Set<User> users = new HashSet<User>();
        users.add(user1);
        users.add(user2);
        /*Set<Project> projects = new HashSet<Project>(0);
        projects.add(project);
        user2.setProjects(projects);
        userBo.add(user2);*/
        
        project.setUsers(users);
        LOGGER.debug("EditProject - project.users.size: " + project.getUsers().size());
        projectBo.edit(project);
        LOGGER.debug("EditProject - project.users.size: " + project.getUsers().size());
        
        
        return Action.SUCCESS;
    }
    
    public void prepare() throws Exception {
 
    }
 
    private Project getProject(Integer projectId) {
        LOGGER.debug("Get project with id = " + projectId);
        if (projectId != null) {
        	Project project = projectBo.findById(projectId);
                return project;
        }
        return null;
    }
    
    public String listProjectsForUser() {
    	
    	Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    	String userName = auth.getName();
    	
    	User user = userBo.findByUsername(userName);
    	projects = (List) user.getProjects();
    	
    	return Action.SUCCESS;
    }
    
    
 
	public List<String> getUsersSystem() {
		return usersSystem;
	}

	public void setUsersSystem(List<String> usersSystem) {
		this.usersSystem = usersSystem;
	}

	public String getAddedUser() {
		return addedUser;
	}

	public void setAddedUser(String addedUser) {
		this.addedUser = addedUser;
	}

	public Integer getUserId() {
		return userId;
	}

	public void setUserId(Integer userId) {
		this.userId = userId;
	}

	public Project getProject() {
		return project;
	}

	public void setProject(Project project) {
		this.project = project;
	}
    
    public List getProjects() {
		return projects;
	}

	public void setProjects(List projects) {
		this.projects = projects;
	}

	public Integer getProjectId() {
		return projectId;
	}

	public void setProjectId(Integer projectId) {
		this.projectId = projectId;
	}

	public int getCustomerId() {
		return customerId;
	}

	public void setCustomerId(int customerId) {
		this.customerId = customerId;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public ProjectBo getProjectBo() {
		return projectBo;
	}

	public void setProjectBo(ProjectBo projectBo) {
		this.projectBo = projectBo;
	}
	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public Integer getNextIterationLenght() {
		return nextIterationLenght;
	}

	public void setNextIterationLenght(Integer nextIterationLenght) {
		this.nextIterationLenght = nextIterationLenght;
	}

	public Integer getCurrentIterationNumber() {
		return currentIterationNumber;
	}

	public void setCurrentIterationNumber(Integer currentIterationNumber) {
		this.currentIterationNumber = currentIterationNumber;
	}

	public Date getPredictedEndDate() {
		return predictedEndDate;
	}

	public void setPredictedEndDate(Date predictedEndDate) {
		this.predictedEndDate = predictedEndDate;
	}

	public void setCustomerId(Integer customerId) {
		this.customerId = customerId;
	}

	
	public UserBo getUserBo() {
        return userBo;
    }
 
    public void setUserBo(UserBo userBo) {
        this.userBo = userBo;
    }

	public ActivityDao getActivityDao() {
		return activityDao;
	}

	public void setActivityDao(ActivityDao activityDao) {
		this.activityDao = activityDao;
	}

	/**
	 * @param users the users to set
	 */
	public void setUsers(Set<User> users) {
		this.users = users;
	}

	/**
	 * @return the users
	 */
	public Set<User> getUsers() {
		return users;
	}

	/**
	 * @param iterations the iterations to set
	 */
	public void setIterations(Set<Iteration> iterations) {
		this.iterations = iterations;
	}

	/**
	 * @return the iterations
	 */
	public Set<Iteration> getIterations() {
		return iterations;
	}

	/**
	 * @param defaultIterationLenght the defaultIterationLenght to set
	 */
	public void setDefaultIterationLenght(Integer defaultIterationLenght) {
		this.defaultIterationLenght = defaultIterationLenght;
	}

	/**
	 * @return the defaultIterationLenght
	 */
	public Integer getDefaultIterationLenght() {
		return defaultIterationLenght;
	}

	 /**
	 * @param sessionBean the sessionBean to set
	 */
	public void setSessionBean(SessionHelper sessionBean) {
		this.sessionBean = sessionBean;
	}

	/**
	 * @return the sessionBean
	 */
	public SessionHelper getSessionBean() {
		return sessionBean;
	}

	public void setServletRequest(HttpServletRequest request){
		  this.request = request;
		  }

		  public HttpServletRequest getServletRequest(){
		  return request;
		  }

		  public void setServletResponse(HttpServletResponse response){
		  this.response = response;
		  }

		  public HttpServletResponse getServletResponse(){
		  return response;
		  }

	
}